package dataView

import (
	"context"
	"encoding/json"
	"math"

	"gitee.com/liuxuezhan/ar-platform/admin-api/internal/svc"
	"gitee.com/liuxuezhan/ar-platform/admin-api/internal/types"
	"gitee.com/liuxuezhan/ar-platform/admin-api/pkg/code"
	"gitee.com/liuxuezhan/ar-platform/admin-api/pkg/common"

	"gitee.com/liuxuezhan/ar-platform/rpc-client/setting/client/dataview"
	"gitee.com/liuxuezhan/ar-platform/rpc-client/setting/rpc"
	"gitee.com/liuxuezhan/ar-platform/rpc-client/userServiceClient/userrpc"
	"github.com/zeromicro/go-zero/core/logc"

	"github.com/zeromicro/go-zero/core/logx"
)

type DataViewLogListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 历史记录
func NewDataViewLogListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DataViewLogListLogic {
	return &DataViewLogListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *DataViewLogListLogic) DataViewLogList(req *types.DataViewLogListReq) (resp *types.DataViewLogListData, err error) {
	resData := make([]types.DataViewLogListDataItem, 0)

	resp = &types.DataViewLogListData{
		Pagination: types.Pagination{
			PageSize:  int32(req.Size),
			Page:      int32(req.Page),
			Total:     0,
			TotalPage: 0,
		},
		List: resData,
	}

	if req.ModelType != 0 {
		if _, ok := common.All[req.ModelType]; !ok {
			return nil, code.ParamsInvalid
		}
	}

	if req.ModelType != 0 && req.Type != 0 {
		if _, ok := common.All[req.ModelType][req.Type]; !ok {
			return nil, code.ParamsInvalid
		}
	}

	u, err := l.svcCtx.SettingService.DataView.DataViewLogList(l.ctx, &dataview.DataViewLogListReq{
		MerchantId: 1,                            // 商户ID
		ModelType:  rpc.ModelType(req.ModelType), // 模块类型,1:用户资产,2:用户基础,3:运营,9:其他
		Type:       req.Type,                     // 具体类型
		Page:       req.Page,
		Size:       req.Size})

	if err != nil {
		logc.Error(l.ctx, "DataViewLogList err:", err)
		return nil, err
	}

	if u.Code != int64(code.SettingRpcSuccessful.Code()) {
		return nil, code.BusinessFailure
	}

	userIdMap := map[int64]int64{}
	for _, v := range u.Data.List {
		userIdMap[v.OperatorId] = v.OperatorId
		old := map[string]interface{}{}
		_ = json.Unmarshal([]byte(v.OldValue), &old)

		newValue := map[string]interface{}{}
		_ = json.Unmarshal([]byte(v.NewValue), &newValue)
		resData = append(resData, types.DataViewLogListDataItem{
			Id:         v.Id,
			MerchantId: v.MerchantId,
			ModelType:  int64(v.ModelType),
			Type:       v.Type,
			NewValue:   newValue,
			OldValue:   old,
			Operator:   v.Operator,
			OperatorId: v.OperatorId,
			Ip:         v.Ip,
			IpAddress:  v.IpAddress,
			UpdatedAt:  v.UpdatedAt,
		})
	}

	userIdList := make([]int64, 0)
	for _, v := range userIdMap {
		userIdList = append(userIdList, v)
	}

	if len(userIdList) > 0 {
		infoResp, err := l.svcCtx.UserServiceRPC.AdminUserNameList(l.ctx, &userrpc.AdminUserNameListRequest{IdList: userIdList})
		if err != nil {
			logc.Error(l.ctx, "UserServiceRPC.AdminUserNameList err:", err)
		}

		if err == nil && len(infoResp.AdminUserNameList) > 0 {
			userResMap := map[int64]string{}
			for _, v := range infoResp.AdminUserNameList {
				userResMap[v.Id] = v.Nickname
			}

			if len(userResMap) > 0 {
				for index, v := range resData {
					if value, ok := userResMap[v.OperatorId]; ok {
						resData[index].Operator = value
					}
				}
			}
		}
	}

	resp.List = resData
	resp.Pagination.Total = u.Data.Count
	resp.Pagination.TotalPage = int64(math.Ceil(float64(u.Data.Count) / float64(resp.Pagination.PageSize)))
	return resp, nil
}
